<?php
/**
 *    Copyright 2010 Show Framework(www.showframework.cn)
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 * 
 *        http://www.apache.org/licenses/LICENSE-2.0
 * 
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 * 应用类，框架入口类
 * 
 * @package Show
 * @name Show_App
 * @author show
 * @since v0.6
 */
final class Show_App
{
    /**
     * 应用程序单件
     *
     * @var Show_App
     */
    private static $instance;
    
    /**
     * 路由器
     *
     * @var Show_Router_Interface
     */
    private $router;
    
    /**
     * 命令
     *
     * @var string
     */
    private $command;
    
    /**
     * 构造函数
     *
     * @return void
     */
    private function __construct()
    {
        /**
         * 初始化命令栈
         */
        $GLOBALS['show']['command_stack'] = array();
    }
    
    /**
     * 获取应用程序实例
     *
     * @return Show_App
     * @since v0.6
     */
    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            $c = __CLASS__;
            self::$instance = new $c;
        }
        return self::$instance;
    }
    
    /**
     * 运行应用程序
     *
     * @return void
     * @since v0.6
     */
    public function run()
    {
        /**
         * filter GPC
         */
        $filter = new Show_Filter_Gpc();
        $filter->filter();
        $this->loadConfig(APP_ROOT . 'config/common.php');
        $this->getCommand();
        $this->initCommandStack();
        $this->router = new Show_Router();
        $this->router->dispatch();
    }
    
    /**
     * 加载应用程序配置
     *
     * @param string $file
     * @return void
     * @since v0.6
     */
    public function loadConfig($file)
    {
        $GLOBALS['show']['config'] = new Show_Config_Default($file);
    }
    
    /**
     * 从url中取出命令
     *
     * @return void
     * @since v0.6
     */
    private function getCommand()
    {
        if (Show_App::config()->url->rewrite) {
            $command = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['SCRIPT_NAME'], 'index.php'));
        } else {
            //$command = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], 'index.php') + 10);
            $command = $_SERVER['PATH_INFO'];
        }
        //去除url中?后面作为get变量的串
        if ($command !== false && ($p = strpos($command, '?')) !== false) {
            $this->command = substr($command, 0, $p);
        } else {
            $this->command = $command;
        }
    }
    
    /**
     * 初始化命令栈
     *
     * @return void
     * @since v0.6
     */
    private function initCommandStack()
    {
        $array = explode('/', $this->command);
        foreach ($array as $value) {
            if ($value !== '') {
                array_push($GLOBALS['show']['command_stack'], $value);
            }
        }
    }
    
    /**
     * 全局函数：获取配置对象
     *
     * @uses Show_App::config()->key->key; Show_App::config()->has('config_key');
     * @return Show_Config_Interface
     */
    public static function config()
    {
        if ($GLOBALS['show']['config'] instanceof Show_Config_Interface) {
            return $GLOBALS['show']['config'];
        } else {
            //trigger_error();
        }
    }
    
    /**
     * 记录日志的函数
     * 可以用来记录错误日志等
     *
     * @param mixed $message
     * @return void
     * @since v0.6
     */
    public static function log($message)
    {
        ob_start();
        var_dump($message);
        $message = ob_get_clean();
        $content = 'Show Log ' . date('Y-m-d H:i:s') . " REQUEST_URI " . $_SERVER['REQUEST_URI'] . "\r\n";
        $content .= $message . "\r\n";
        $file = APP_ROOT . 'log/' . date('Y-m-d') . '.txt';
        if (!file_exists($file)) {
            touch($file);
        }
        file_put_contents($file, $content, FILE_APPEND | LOCK_EX);
    }
    
    /**
     * 全局函数，发送一个字符集http头
     *
     * @return void
     * @since v0.6
     */
    public static function charset()
    {
        header("Content-type: text/html; charset=utf-8");
    }
    
    /**
     * 转向
     *
     * @param string $url 转向地址
     * @param int $time 转向之前等待时间
     * @param string $msg 转向之前的提示
     * @return void
     * @since v0.6
     */
    public function redirect($url, $time, $msg)
    {
        $url = str_replace(array("\n", "\r"), '', $url);
        if (empty($msg)) {
            $msg = "系统将在{$time}秒之后自动跳转到{$url}";
        }
        if (!headers_sent()) {
            if ($time === 0) {
                header("Location: " . $url);
            } else {
                header("refresh:{$time};url={$url}");
                echo($msg);
            }
            exit();
        } else {
            $str = sprintf('<meta http-equiv="Refresh" content="%d;url=%s">', $time, $msg);
            if ($time != 0) {
                $str .= $msg;
            }
            exit($str);
        }
    }
}
?>